package device_ctr;
public class TinyEncryptor {
	private long delta = 0x9E3779B9;
	// a key schedule constant
	private int  k0=28395;
	private  int k1=93648;
	private  int  k2=20841;
	private  int  k3=26304; 
	public void set_new_pass(int new_k3){
		k3=new_k3;
	}
	public void reset_new_pass(){
		k3=26304;
	}
	public String Str_Code(String txt){
		int[] temp ;
		int j;
		String value=txt;
		String code_txt="";
		while (value.length()%8>0)
			value=value + " ";
		temp=new int[value.length()];
		for(int hh=0;hh<value.length();hh++){
			temp[hh]=(int)value.charAt(hh);
		}
		int [] jieguo;
		jieguo=new int [value.length()/4];
        for(j=0;j<temp.length;j+=8)
        {
            int [] ll;
            int linshi_int=0;
            ll=new int [2];
            ll[0]=0;
            ll[1]=0;
            
            for(int wei_zhi=0;wei_zhi<4;wei_zhi++){
            	linshi_int=temp[wei_zhi+j];
                linshi_int=linshi_int<<((wei_zhi)*8);
                ll[0]=ll[0]+linshi_int;
            }
            
            for(int wei_zhi=0;wei_zhi<4;wei_zhi++){
            	linshi_int=temp[wei_zhi+j+4];
                linshi_int=linshi_int<<((wei_zhi)*8);
                ll[1]=ll[1]+linshi_int;
            }
            code(ll);
            jieguo[0+j/4]=ll[0];
            jieguo[1+j/4]=ll[1];
            //0 0  1
            //8 2  3
            //16 4   5
        }
        for(j=0;j<value.length()/4;j++)
        {
        	String zhuan_huan=Integer.toHexString(jieguo[j]);
        	while(zhuan_huan.length()<8){
        		zhuan_huan="0"+zhuan_huan;
        	}
            code_txt=code_txt + zhuan_huan.substring(6, 8);
            code_txt=code_txt + zhuan_huan.substring(4, 6);
            code_txt=code_txt + zhuan_huan.substring(2, 4);
            code_txt=code_txt + zhuan_huan.substring(0, 2);
        }
        return code_txt.toUpperCase();
	}
	public String Str_DeCode(String txt){
		int[] temp ;
		String result ;
		String value=txt.toLowerCase();
		if (value.length()%8>0){
			return "Error for fomat";
		}
		else
		{
			temp=new int[value.length()/8];
			result="";
			for(int hh=0;hh<value.length();hh+=8){
				
				try {
					temp[hh/8]=hex_2_int(value.substring(0+hh, 8+hh));
					
				} catch (NumberFormatException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
					return "Error for fomat";
				}
			}
			
			for(int n=0;n<temp.length;n+=2){
				int [] lin_shi_bian;
				lin_shi_bian=new int[2];
				lin_shi_bian[0]=temp[n];
				lin_shi_bian[1]=temp[n+1];
				decode(lin_shi_bian);
				result=result+int_2_string(lin_shi_bian[0]);
				result=result+int_2_string(lin_shi_bian[1]);
			}
			return result;
			
		}
	}
	private String int_2_string(int k){

		int value=k;
		char a[];
		a= new char[4];
		a[0]=(char) (value%256);
		value=value>>8;
		a[1]=(char) (value%256);
		value=value>>8;
		a[2]=(char) (value%256);
		value=value>>8;
		a[3]=(char) (value%256);
		return new String (a);
	}
	private void code(int[] v) {
		int y=v[0];
		int z=v[1];
		int sum=0;
		int n=32;
		
		while (n-- > 0) {
			sum += delta;
			y += ((z << 4) + k0) ^ (z + sum) ^ ((z >> 5) + k1);
			z += ((y << 4) + k2) ^ (y + sum) ^ ((y >> 5) + k3);
		}
		v[0]=y; 
		v[1]=z;
	}
	void decode (int[] v) {
		int y=v[0];
		int z=v[1];
		int sum=0xC6EF3720;
		int n=32; // set up
		while (n-- > 0) {
			z -= ((y << 4) + k2) ^ (y + sum) ^ ((y >> 5) + k3);
			y -= ((z << 4) + k0) ^ (z + sum) ^ ((z >> 5) + k1);
			sum -= delta;
		}
		v[0]=y;
		v[1]=z;
	}
	private int hex_2_int(String hex){
		int a,b,c,d;
		int fu=0;
		a=Integer.valueOf(hex.substring(6, 8),16);
		b=Integer.valueOf(hex.substring(4, 6),16);
		c=Integer.valueOf(hex.substring(2, 4),16);
		d=Integer.valueOf(hex.substring(0, 2),16);
		if (a>127){
			fu=1;
			a=(256-a);
			a=a*16777216;
		}
		else{
			a=a*16777216;
		}
		b=b*65536;
		c=c*256;
		
		if (fu==0){
			return a+b+c+d;
		}
		else{
			return -(a-b-c-d);
		}
	}
	
}
